package com.shiguang.springboot.config;

import com.shiguang.springboot.interfac.WebServer;
import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.Map;

/**
 * @program: shiguang-springboot
 * @description: 主启动类
 * @author: chaidl  ！
 * @create: 2022-07-17 19:51
 */
public class ShiGuangSpringApplication {
	/**
	 * 创建一个Spring容器
	 * 创建Tomcat对象
	 * 生成DispatcherServlet对象，并且和前面创建出来的Spring容器进行绑定
	 * 将DispatcherServlet添加到Tomcat中
	 * 启动Tomcat
	 *
	 * @param clazz
	 */
	public static void run(Class clazz) {
		//1.创建一个Spring容器
		AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
		applicationContext.register(clazz);
		applicationContext.refresh();
		WebServer webServer = getWebServer(applicationContext);
		webServer.start();
		//startTomcat(applicationContext);
	}
	
	/**
	 * 获取WEB容器
	 * @param applicationContext
	 * @return
	 */
	private static WebServer getWebServer(AnnotationConfigWebApplicationContext applicationContext) {
		Map<String, WebServer> beansOfType = applicationContext.getBeansOfType(WebServer.class);
		//为空，报错
		if (beansOfType.isEmpty()) {
			throw new NullPointerException("servlet容器为空");
		}
		//Jetty和tomcat同时存在也报错
		if (beansOfType.size() > 1) {
			throw new IllegalStateException("servlet容器不能同时出现多个");
		}
		//返回唯一
		return beansOfType.values().stream().findFirst().get();
	}
	
	public static void startTomcat(WebApplicationContext applicationContext) {
		System.out.println("开始启动Tomcat");
		Tomcat tomcat = new Tomcat();
		
		Server server = tomcat.getServer();
		Service service = server.findService("Tomcat");
		
		Connector connector = new Connector();
		connector.setPort(8081);
		
		Engine engine = new StandardEngine();
		engine.setDefaultHost("localhost");
		
		Host host = new StandardHost();
		host.setName("localhost");
		
		String contextPath = "";
		Context context = new StandardContext();
		context.setPath(contextPath);
		context.addLifecycleListener(new Tomcat.FixContextListener());
		
		host.addChild(context);
		engine.addChild(host);
		
		service.setContainer(engine);
		service.addConnector(connector);
		
		tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
		context.addServletMappingDecoded("/*", "dispatcher");
		
		try {
			tomcat.start();
		} catch (LifecycleException e) {
			e.printStackTrace();
		}
		
	}
}
